/* 
 * File:   Interpretador.cpp
 * Author: Henrique
 * 
 * Created on 29 de Março de 2010, 08:29
 */
#include <stdio.h>
#include <string.h>
#include <string>
#include <ctype.h>
#include <iostream>
#include "Interpretador.h"
#include "fori.h"
#include "ifthenelse.h"
#include "lacoWhile.h"

Interpretador::Interpretador() {
}

Interpretador::Interpretador(const Interpretador& orig) {
}

Interpretador::~Interpretador() {
}

double* Interpretador::execute(std::vector<std::string> programa, double var[]) {


    double *memTemp = new double[26];
    memTemp = var;
    

    for (int i = 0; i < programa.size(); i++) {


        std::string comando;
        std::string so = programa.at(i);
        //     std::cout << so << std::endl;
        for (int j = 0; j < so.size(); j++) {
            char d = so.at(j);
            if (d == ' ') {
                so.erase(j, 1);
                j--;

            } else {
                comando.append(so);
                break;
            }

        }
        for (int g = comando.size() - 1;g >= 0; g--) {
            char x = comando.at(g);
            comando.erase(g, 1);
            if (x == ';');
            break;


        }

        //   std::cout << comando << std::endl;
        //     comando  = comando.erase(comando.size()-1);
        bool verifica = true;
        //write string | var
        std::string writeStrVar = comando.substr(0, 8);
        if (writeStrVar.compare("writeStr") == 0 | writeStrVar.compare("writeVar") == 0) {
            verifica = false;
            if (writeStrVar.compare("writeStr") == 0) {
                std::string impressao = "";
                impressao = comando.substr(10, comando.size() - 13);

                writeStr *writestr = new writeStr(impressao);
                writestr->execute();
            }
            if (writeStrVar.compare("writeVar") == 0) {
                char impressao;
                impressao = comando.at(comando.size() - 2);
                double value = memTemp[(int) impressao - (int) 'a'];
                writeVar *writevar = new writeVar(impressao);
                writevar->execute(memTemp);
            }
        }
        //write ln
        std::string writeln = comando.substr(0, 7);
        if (writeln.compare("writeln") == 0) {
            verifica = false;
            writeLn *writeline = new writeLn();
            writeline->execute();
        }
        //read var
        std::string readin = comando.substr(0, 4);
        if (readin.compare("read") == 0) {
            verifica = false;
            char impressao = comando.at(comando.size() - 3);
            leitor::read *readline = new leitor::read(impressao);
            readline->execute();
            memTemp[(int) readline->getChar() - (int) 'a'] = readline->getDouble();
        }
        //for
        std::string for_each = comando.substr(0, 3);
        if (for_each.compare("for") == 0) {
            verifica = false;
            fori *lacoFor = new fori(comando, memTemp, programa);

            memTemp = lacoFor->executaFor(comando);
            for (int t = 0; t < 26; t++) {
                memTemp[t];
            }
            i = i + lacoFor->numberCom + 1;
        }
        //while
        std::string whilei = comando.substr(0, 5);
        if (whilei.compare("while") == 0) {
            verifica = false;
            lacoWhile *lacoW = new lacoWhile(comando,memTemp, programa);
            memTemp = lacoW->execute();

        }
        //if
        std::string ifi = comando.substr(0, 2);
        if (ifi.compare("if") == 0) {
            verifica = false;
            ifthenelse *executaIf = new ifthenelse(comando, programa, memTemp);
            memTemp = executaIf->execute();
        }
        //comando de atribuicao
        std::string atrib = comando;
        if (verifica) {
            std::string temp;
            for (int i = 0; i < comando.size(); i++) {
                char c = comando.at(i);
                if (c != ' ') {
                    temp.append(1, c);
                }
            }

            atribuicao *executaAtribuicao = new atribuicao(temp.at(0), memTemp);
            double v = executaAtribuicao->processamentoAtribuicao(atrib);
            memTemp[(int) temp.at(0)-(int) 'a'] = executaAtribuicao->getMem()[(int) temp.at(0)-(int) 'a'];


        }
    }
    return memTemp;
}


